package net.inttes.lotura.binding.value.support;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.beans.VetoableChangeSupport;

import net.inttes.lotura.binding.value.PropertyChangePublisher;



public abstract class AbstractPropertyChangePublisher implements
        PropertyChangePublisher {

    private transient PropertyChangeSupport changeSupport;

    private transient VetoableChangeSupport vetoSupport;
    

    public final void addPropertyChangeListener(PropertyChangeListener listener) {
        if (listener == null) { return; }
        if (changeSupport == null) {
            changeSupport = new PropertyChangeSupport(this);
        }
        changeSupport.addPropertyChangeListener(listener);
    }

    
    public final void removePropertyChangeListener(
            PropertyChangeListener listener) {
        if (listener == null || changeSupport == null) { return; }
        changeSupport.removePropertyChangeListener(listener);
    }

    public final void addPropertyChangeListener(String propertyName,
            PropertyChangeListener listener) {
        if (listener == null) { return; }
        if (changeSupport == null) {
            changeSupport = new PropertyChangeSupport(this);
        }
        changeSupport.addPropertyChangeListener(propertyName, listener);
    }

    public final void removePropertyChangeListener(String propertyName,
            PropertyChangeListener listener) {
        if (listener == null || changeSupport == null) { return; }
        changeSupport.removePropertyChangeListener(propertyName, listener);
    }

    public final void addVetoableChangeListener(
            VetoableChangeListener listener) {
        if (listener == null) { return; }
        if (vetoSupport == null) {
            vetoSupport = new VetoableChangeSupport(this);
        }
        vetoSupport.addVetoableChangeListener(listener);
    }

    public final void removeVetoableChangeListener(
            VetoableChangeListener listener) {
        if (listener == null || vetoSupport == null) { return; }
        vetoSupport.removeVetoableChangeListener(listener);
    }

    public final void addVetoableChangeListener(String propertyName,
            VetoableChangeListener listener) {
        if (listener == null) { return; }
        if (vetoSupport == null) {
            vetoSupport = new VetoableChangeSupport(this);
        }
        vetoSupport.addVetoableChangeListener(propertyName, listener);
    }

    public final void removeVetoableChangeListener(String propertyName,
            VetoableChangeListener listener) {
        if (listener == null || vetoSupport == null) { return; }
        vetoSupport.removeVetoableChangeListener(propertyName, listener);
    }

    public final PropertyChangeListener[] getPropertyChangeListeners() {
        if (changeSupport == null) { return new PropertyChangeListener[0]; }
        return changeSupport.getPropertyChangeListeners();
    }

    public final PropertyChangeListener[] getPropertyChangeListeners(
            String propertyName) {
        if (changeSupport == null) { return new PropertyChangeListener[0]; }
        return changeSupport.getPropertyChangeListeners(propertyName);
    }

    public final VetoableChangeListener[] getVetoableChangeListeners() {
        if (vetoSupport == null) { return new VetoableChangeListener[0]; }
        return vetoSupport.getVetoableChangeListeners();
    }

    public final VetoableChangeListener[] getVetoableChangeListeners(
            String propertyName) {
        if (vetoSupport == null) { return new VetoableChangeListener[0]; }
        return vetoSupport.getVetoableChangeListeners(propertyName);
    }

    protected final void firePropertyChange(String propertyName,
            Object oldValue, Object newValue) {
        PropertyChangeSupport aChangeSupport = this.changeSupport;
        if (aChangeSupport == null) { return; }
        aChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
    }

    protected final void firePropertyChange(String propertyName,
            boolean oldValue, boolean newValue) {
        PropertyChangeSupport aChangeSupport = this.changeSupport;
        if (aChangeSupport == null) { return; }
        aChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
    }

    protected final void firePropertyChange(String propertyName,
            double oldValue, double newValue) {
        firePropertyChange(propertyName, new Double(oldValue), new Double(
                newValue));
    }

    protected final void firePropertyChange(String propertyName,
            float oldValue, float newValue) {
        firePropertyChange(propertyName, new Float(oldValue), new Float(
                newValue));
    }

    protected final void firePropertyChange(String propertyName, int oldValue,
            int newValue) {
        PropertyChangeSupport aChangeSupport = this.changeSupport;
        if (aChangeSupport == null) { return; }
        aChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
    }

    protected final void firePropertyChange(String propertyName, long oldValue,
            long newValue) {
        firePropertyChange(propertyName, new Long(oldValue), new Long(newValue));
    }

    protected final void firePropertiesChanged() {
        firePropertyChange(null, null, null);
    }

    protected final void fireVetoableChange(String propertyName,
            Object oldValue, Object newValue) throws PropertyVetoException {
        VetoableChangeSupport aVetoSupport = this.vetoSupport;
        if (aVetoSupport == null) { return; }
        aVetoSupport.fireVetoableChange(propertyName, oldValue, newValue);
    }

    protected final void fireVetoableChange(String propertyName,
            boolean oldValue, boolean newValue) throws PropertyVetoException {
        VetoableChangeSupport aVetoSupport = this.vetoSupport;
        if (aVetoSupport == null) { return; }
        aVetoSupport.fireVetoableChange(propertyName, oldValue, newValue);
    }

    protected final void fireVetoableChange(String propertyName,
            double oldValue, double newValue) throws PropertyVetoException {
        fireVetoableChange(propertyName, new Double(oldValue), new Double(
                newValue));
    }

    protected final void fireVetoableChange(String propertyName, int oldValue,
            int newValue) throws PropertyVetoException {
        VetoableChangeSupport aVetoSupport = this.vetoSupport;
        if (aVetoSupport == null) { return; }
        aVetoSupport.fireVetoableChange(propertyName, oldValue, newValue);
    }

    protected final void fireVetoableChange(String propertyName,
            float oldValue, float newValue) throws PropertyVetoException {
        fireVetoableChange(propertyName, new Float(oldValue), new Float(
                newValue));
    }

    protected final void fireVetoableChange(String propertyName, long oldValue,
            long newValue) throws PropertyVetoException {
        fireVetoableChange(propertyName, new Long(oldValue), new Long(newValue));
    }

    protected boolean hasChanged(Object currentValue, Object proposedValue) {
    	return !(currentValue == proposedValue || (currentValue != null && currentValue.equals( proposedValue )));
//        return !ObjectUtils.nullSafeEquals(currentValue, proposedValue);
    }

    protected final boolean hasChanged(boolean currentValue, boolean proposedValue) {
        return currentValue != proposedValue;
    }

    protected final boolean hasChanged(int currentValue, int proposedValue) {
        return currentValue != proposedValue;
    }

    protected final boolean hasChanged(long currentValue, long proposedValue) {
        return currentValue != proposedValue;
    }

    protected final boolean hasChanged(float currentValue, float proposedValue) {
        return currentValue != proposedValue;
    }

    protected final boolean hasChanged(double currentValue, double proposedValue) {
        return currentValue != proposedValue;
    }

}